package com.epin.util;

import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

import com.feilong.core.Validator;
import com.epin.base.vo.MergeExcelEntity;

import net.sf.jxls.exception.ParsePropertyException;
import net.sf.jxls.transformer.XLSTransformer;

public class TemplateFileUtil {

	/**
	 * <p>获取模板文件</p>
	 * 
	 * @param tempName 模板名
	 * 
	 * @return InputStream
	 * @throws FileNotFoundException
	 */
    public InputStream getTemplates(String tempName) throws FileNotFoundException {
    	InputStream stream = getClass().getClassLoader().getResourceAsStream("excel-templates/" + tempName);
        return stream;
    }
    
    
    /**
     * <p>根据模板输出Excel</p>
     * 
     * @param tempName 模板名
     * @param beanParams 数据Map
     * @param response HTTP响应体
     */
    public static void exportExcelByTemplate(String tempName, Map<String, Object> beanParams, HttpServletResponse response){
    	
    	if (Validator.isNullOrEmpty(response)) {
			return;
		}
    	
    	XLSTransformer transformer = new XLSTransformer();
        
        try (InputStream in = 
        		new BufferedInputStream(new TemplateFileUtil().getTemplates(tempName));
        	OutputStream os = 
        			response.getOutputStream()) {
        	
            Workbook workbook = transformer.transformXLS(in, beanParams);
            
            //将内容写入输出流并把缓存的内容全部发出去  
            workbook.write(os);  
            os.flush();
            
        } catch (IOException | ParsePropertyException | InvalidFormatException e) {
			e.printStackTrace();
		} 
    	
    }
    
    
    /**
     * <p>根据模板输出Excel</p>
     * 
     * @param tempName 模板名
     * @param beanParams 数据Map
     * @param response HTTP响应体
     * @param entity Excel合并辅助对象
     */
    public static void exportExcelByTemplate(String tempName, Map<String, Object> beanParams, HttpServletResponse response, MergeExcelEntity entity){
    	
    	if (Validator.isNullOrEmpty(response) || Validator.isNullOrEmpty(entity)) {
			return;
		}
    	
    	XLSTransformer transformer = new XLSTransformer();
    	
    	try(InputStream in = 
        		new BufferedInputStream(new TemplateFileUtil().getTemplates(tempName));
        	OutputStream os = 
        			response.getOutputStream()) {
        	
            Workbook workbook = transformer.transformXLS(in, beanParams);
            
            // 合并
            workbook = TemplateFileUtil.mergeCellForWorkbook(entity, workbook);

            //将内容写入输出流并把缓存的内容全部发出去  
            workbook.write(os);
            os.flush();
        } catch (IOException | ParsePropertyException | InvalidFormatException e) {  
            e.printStackTrace();
        }
    }
    
    
    /**
     * <p>设置文件名</p>
     * 
     * @param fileName 文件名
     * @param response 对象
     * 
     * @return HttpServletResponse
     */
    public static HttpServletResponse setResponseExcelExport(String fileName, HttpServletResponse response) {
		
    	if (response == null) {
			return response;
		}
    	
    	// 设置传输参数
	    String name = "";
	    try {
	    	name = java.net.URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return response;
		}
	    
	    response.setContentType("application/vnd.ms-excel"); 
	    // 设置文件名，请严格按照rfc231标准设置
	    response.setHeader("content-disposition", "attachment;filename*=utf-8'zh_cn'" + name + ".xls");
    	
	    return response;
	}
    
    
    /**
     * <p>帮助workbook合并单元格</p>
     * 
     * @param entity Excel合并辅助对象
     * @param workbook 对象
     * 
     * @return Workbook
     */
    private static Workbook mergeCellForWorkbook(MergeExcelEntity entity, Workbook workbook) {
    	
    	if (Validator.isNullOrEmpty(entity) || Validator.isNullOrEmpty(workbook)) {
			return workbook;
		}
    	
    	if (Validator.isNullOrEmpty(entity.getMergeCol())) {
    		return workbook;
		}
    	
    	if (Validator.isNullOrEmpty(entity.getMergeRowSize())) {
			return workbook;
		}
    	
    	int startRow = entity.getStartRow() < 0 ? 0 : entity.getStartRow();
    	int colSize = entity.getColSize() < 0 ? 0 : entity.getColSize();
    	int sheetNo = entity.getSheetNo() < 0 ? 0 : entity.getSheetNo();
    	
    	// 合并
        Sheet sheet = workbook.getSheetAt(sheetNo);
        for (Integer size : entity.getMergeRowSize()) {
			if (size > 0) {
				int endRow = startRow + size - 1;
				
				for(int i = 0;i < colSize;i++){
					if (entity.getMergeCol().contains(i)) {
						sheet.addMergedRegion(new CellRangeAddress(startRow, endRow, i, i));
					}
				}
				
				startRow = endRow + 1;
			}
		}
        
        return workbook;
	}
    
}